package com.whately.core.base.verifycode;

import com.whately.core.base.annotation.IgnoreSession;
import com.whately.core.base.exception.ServiceError;
import com.whately.core.base.exception.ServiceException;
import com.whately.core.base.helper.SmsMessageTemplate;
import com.whately.core.base.model.ApiResponse;
import com.whately.core.base.utils.MobileUtils;
import com.whately.core.base.constant.VerifyCodeTypeEnum;
import com.whately.core.base.constant.WhatelyCoreSmsEnum;
import com.whately.core.base.sms.SmsFacade;
import com.whately.core.base.verifycode.util.SmsGenerateResult;
import com.whately.core.base.verifycode.vo.req.FetchSmsCodeReqVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 验证码
 * 包括图片验证码 ，短信验证码等
 */
@RestController
@RequestMapping("/api")
@Slf4j
@Api(tags = "验证码-短信")
//@ApiSort(9999002)
public class WhatelyVerifyCodeSmsController {

    @Value("${qcloud.sms.verifyChannel:}")
    private String smsVerifyChannel;

    @Autowired
    private WhatelyVerifyCodeFacade whatelyVerifyCodeFacade;

    @Autowired
    private SmsFacade smsFacade;


    /********************************************************
     * 短信验证码
     * 图形验证码采用hash存储 ，
     *  包括 value ：mobile+code  ;
     *      count ：访问计数  ;
     *******************************************************/
    @PostMapping(params = "method=whately.core.verifyCode.getSms")
    @IgnoreSession
    @ApiOperation("发送短信验证码(依赖图形校验)")
    public ApiResponse<String> getSmsVerifyCode(@RequestBody FetchSmsCodeReqVo requestVo) {
        Integer type = requestVo.getType();
        String mobile = requestVo.getMobile();
        String imgToken = requestVo.getImgToken();
        String imgVerifyCode = requestVo.getImgVerifyCode();
        VerifyCodeTypeEnum verifyCodeType = VerifyCodeTypeEnum.getVerifyCodeType(type);


        //TODO 这个参数不确定是不是需要，暂时先不加
        //String sndToken = null;//requestVo.getToken();
        //String token = StringUtils.isNotBlank(imgToken)?imgToken:sndToken;

        String token = imgToken;

        if(verifyCodeType==null){
            log.error("getSmsVerifyCode verifyCodeType is null ,type {} ,mobile {} ,imgVerifyCode {}",type,mobile,imgVerifyCode);
            throw new ServiceException(ServiceError.REQUEST_PARAMETER_ERROR);
        }

        if(!MobileUtils.isPhone(mobile)){
            log.error("getSmsVerifyCode verifyCodeType mobile is not correct ,type {} ,mobile {},imgVerifyCode {},token {}",type,mobile,imgVerifyCode,imgToken);
            throw new ServiceException(ServiceError.VERIFY_CODE_SMS_ERROR.getCode(),"手机号格式错误");
        }

        if(StringUtils.isBlank(token)||token.length()<=16){
            log.error("getSmsVerifyCode verifyCodeType token error ,type {} ,mobile {},imgVerifyCode {},token {}",type,mobile,imgVerifyCode,imgToken);
            throw new ServiceException(ServiceError.VERIFY_CODE_SMS_ERROR.getCode(),"token格式错误");
        }


        if(StringUtils.isBlank(imgVerifyCode)){
            log.error("getSmsVerifyCode verifyCodeType token error ,type {} ,mobile {},imgVerifyCode {},imgToken {}",type,mobile,imgVerifyCode,imgToken);
            throw new ServiceException(ServiceError.VERIFY_CODE_IMG_ERROR.getCode(),"图形验证码不能为空");
        }

        //获取验证码之前，需要检验图形验证码是否正确
        whatelyVerifyCodeFacade.checkImgVerifyCodeFromAesToken(verifyCodeType,imgToken,mobile,imgVerifyCode);

        //通过验证发送短信
        String smsToken = sendSmsAndReturnToken(verifyCodeType,mobile);

        return ApiResponse.<String>builder().message("验证码已发出，请注意查收!").data(smsToken).build();
    }

    /**
     * 发送短信，并返回token
     */
    private String sendSmsAndReturnToken(VerifyCodeTypeEnum verifyCodeType, String mobile){
        //检查是否获取验证码，超越
        whatelyVerifyCodeFacade.checkSmsSendRule(mobile);

        //通过后，发送短信
        WhatelyCoreSmsEnum smsEnum = WhatelyCoreSmsEnum.getSmsByVerifyCodeType(verifyCodeType);
        int expireMinutes = smsEnum.getExpireMinutes();

        SmsGenerateResult generateResult =  whatelyVerifyCodeFacade.sendSmsVerifyCode(verifyCodeType,mobile, expireMinutes);

        String code=generateResult.getSmsCode();
        String newToken = generateResult.getToken();
        boolean sendFlag=generateResult.isSendFlag();

        //不是false，就发送
        if(sendFlag){
            //发送短信
            String msgContent = SmsMessageTemplate.getReplacedContent(smsEnum.getContent(),code,expireMinutes);

            //走威海人力资源联调账号的短信，
            if("whrsChannel".equalsIgnoreCase(smsVerifyChannel)&&WhatelyCoreSmsEnum.openWhrsSmsChannel(verifyCodeType)){
                smsFacade.sendWhrlzxSms(mobile,msgContent);
            }else {
                smsFacade.sendSms(mobile,msgContent);
            }
        }else{
            log.warn("sms send not called ,sms code {},mobile {}",code,mobile);
        }
        return newToken;
    }




    /***********************************************
     * 结合风控，发送验证码
     ***********************************************/
    /*
    @PostMapping(params = "method=whately.core.verifyCode.getSmsBeyondRisk")
    @IgnoreSession
    //@ApiOperation("发送短信验证码(依赖风控校验)")
    @InnerApi
    public ApiResponse<WhatelySmsSendResultRespVO> getSmsBeyondRisk(@RequestBody WhatelySmsCodeWithRiskReqVo requestVo) {
        if(StringUtils.isBlank(requestVo.getMobile())||!MobileUtils.isPhoneSimple(requestVo.getMobile())){
            log.error("getSmsBeyondRisk mobile is blank");
            throw new ServiceException(ServiceError.REQUEST_PARAMETER_ERROR);
        }

        //设置riskID,用作风控
        boolean checkPass = baseLoginCheckHelper.getRiskCheckResult(verifyCodeType,requestVo.getMobile());

        WhatelySmsSendResultRespVO model = new WhatelySmsSendResultRespVO();
        if(checkPass){
            //通过验证发送短信
            String smsToken = sendSmsAndReturnToken(verifyCodeType,requestVo.getMobile());

            WhatelySmsSendResultRespVO newModelAfterSendSms = new WhatelySmsSendResultRespVO();
            newModelAfterSendSms.setCheckPass(true);
            newModelAfterSendSms.setToken(smsToken);//使用新的sms token 作为返回值
            return ApiResponse.<WhatelySmsSendResultRespVO>builder().message("验证码已发出，请注意查收!").data(newModelAfterSendSms).build();
        }else{
            model.setCheckPass(false);
            model.setToken(StringUtils.EMPTY);
            return ApiResponse.<WhatelySmsSendResultRespVO>builder().message("请先获取图形验证码").data(model).build();
        }
    }

     */

}
